/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "ui2D编辑视口.h"


C_2D编辑视口* C_2D编辑视口::g当前操作2D编辑视口 = nullptr;

static uint32	g网格线绘制属性 = 0;

static bool g移动视口 = false;

static E_事件是否传递 on_2D编辑视口按键(C_Widget* self, const S_键盘& ks) {
	
	return E_事件是否传递::e_事件传递_终止;
}

static E_事件是否传递 on_2D编辑视口鼠标按下(C_Widget* self, const E_鼠标按钮& 按钮) {
	if (按钮 == E_鼠标按钮::e_鼠标中键) {
		g移动视口 = true;
	}
	return E_事件是否传递::e_事件传递_终止;
}

static E_事件是否传递 on_2D编辑视口鼠标放开(C_Widget* self, const E_鼠标按钮& 按钮) {
	if (按钮 == E_鼠标按钮::e_鼠标中键) {
		g移动视口 = false;
	}
	return E_事件是否传递::e_事件传递_终止;
}

static E_事件是否传递 on_2D编辑视口移动(C_Widget* self, const ivec4& value) {
	C_2D编辑视口* box = (C_2D编辑视口*)self;

	if (g移动视口) {
		self->m_扩展视口属性->m_中心.x += C_Widget::g_鼠标.abs.x;
		self->m_扩展视口属性->m_中心.y += C_Widget::g_鼠标.abs.y;
		self->m_更新绘制属性 = true;
	}
	return E_事件是否传递::e_事件传递_终止;
}


static void on_2D编辑视口布局(C_Widget* self, C_Widget** w, uint32 num) {
	w[0]->f_setSize(self->m_Size);

	w[0]->m_GlobalScale = self->m_Scale;
}

static void on_2D编辑视口绘制(C_Widget* self, S_2D画布* 画布) {
	C_2D编辑视口& box = *(C_2D编辑视口*)self;
	auto we = box.f_get更新组件();

	box.m_背景 = f_vg_genConvex((*self), *画布, E_填充模式::e_填充面, E_图层混合模式::e_Normal);
	//box.m_刻度 = f_vg_drawConvexElement((*self), *画布, E_填充模式::e_填充面, E_图层混合模式::e_Normal);

	f_ui_set矢量视图图形对象(we.m_W[0], u"节点");

}

static void on_2D编辑视口变换(C_Widget* self) {
	C_2D编辑视口& box = *(C_2D编辑视口*)self;
	float32 dpi = self->m_UIctx->m_DPI;

	float32 X跨度 = 1;
	float32 Y跨度 = 1;
	f_ui_drawTemple_刻度缩放(X跨度, box.m_Scale.x, S_时间轴帧绘制信息::g时间区间缩放);
	f_ui_drawTemple_刻度缩放(Y跨度, box.m_Scale.y, S_时间轴帧绘制信息::g时间区间缩放);

	S_2DConvexRect	区域[4]{};
	S_GPU内存块*	形状[4];
	S_2D颜色包		颜色[4];
	vec2			位置[2];

	区域[0] = { {10*dpi,0}, box.m_Size, {0, 0}, {0,0} };
	形状[0] = &(box.m_UIctx->m_Ctx.m_几何图形->m_平面矩形);
	颜色[0] = S_2D颜色包(S_UI主题::uic_值编辑框背景, 0, 0, DEF_2DShaderType_Checkerboard);
	位置[0] = {};
	f_vg_drawConvex(*box.m_背景, 1, 形状, 区域);
	f_vg_tranform(*box.m_背景, 1, 位置);
	f_vg_color(*box.m_背景, 1, 颜色);
}

C_2D编辑视口::C_2D编辑视口(S_UI渲染环境& ctx) : C_Widget(&ctx) {
	mf_布局 = on_2D编辑视口布局;
	mf_绘制 = on_2D编辑视口绘制;
	mf_变换 = on_2D编辑视口变换;
	f_widget_添加绘制画布(this);
	//mf_鼠标移动 = on_2D编辑视口移动;

	mf_鼠标按键按下 = on_2D编辑视口鼠标按下;
	mf_鼠标按键放开 = on_2D编辑视口鼠标放开;

	m_是否未绘制 = true;
	g当前操作2D编辑视口 = this;

	f_setSize({1024,1024});
	
	auto box = f_ui_创建矢量图形视口(ctx);
	f_添加子组件(box);
	
}

C_2D编辑视口::~C_2D编辑视口() {
	C_Widget::~C_Widget();
}

void C_2D编辑视口::f_数据绘制() {
	for (auto& node : m_节点) {
		//node->f_getStr(m_绘制文本);
	}
	if(m_是否未绘制) return;

	std::vector<vec2> 顶点坐标;
	std::vector<uint32> 顶点索引;

	m_物体.clear();
	for (auto& ob : S_框架::g_拾取物体) {
		switch (ob->m_Type) {
			case E_物体类型::t_网格物体: 
			case E_物体类型::t_多边形: {
				m_物体.insert(ob);
				break;
			}
		}
		std::cout<<"ob " << ob->m_Type << std::endl;
	}

	for (auto& ob : m_物体) {
		if(!ob->m_UserData) continue;

		auto* 物体扩展属性 = f_OE_取可编辑物体属性(ob);

		uint32 面数量 = ((S_多边形*)ob->m_UserData)->m_面.size();
		auto* faces = ((S_多边形*)ob->m_UserData)->m_面.data();

		auto* uv索引 = ((S_多边形*)ob->m_UserData)->m_UV索引.data();
		//auto* uv坐标 = ((S_多边形*)ob->m_UserData)->m_UV.data();
		

		uint32 UV通道显示开关 = 1;
		if (物体扩展属性) {
			UV通道显示开关 = f_prop_UI32(物体扩展属性->m_当前激活UV层);
		}
		

		for (uint32 i = 0; i < 面数量; ++i) {
			auto* uvIndex = faces[i]->uvLoopIndex.data();
			uint32 layerNum = faces[i]->uvLoopIndex.size();
			
			for (uint32 u = 0; u<layerNum; ++u) {
				if (UV通道显示开关 & 1 << u) {
					auto uvLoop = uvIndex[u];
					uint32 loopNum = uvLoop.y;
					for (uint32 j = 0; j < loopNum; ++j) {
						顶点索引.push_back(uv索引[uvLoop.x + j]);
					}
					顶点索引.push_back(uv索引[uvLoop.x]);
					顶点索引.push_back(0xffffffff);
				}
			}
		}

		顶点坐标 = ((S_多边形*)ob->m_UserData)->m_UV;
	}

	if(顶点索引.size()) 顶点索引.pop_back();

}




static void on_2D视口布局(C_Widget* self, C_Widget** w, uint32 num) {
	//f_Widget_计算视口缩放保持偏移比例(self);
	//f_ui_Layout_鼠标位置缩放子组件(w[0], 0.1);
	
}

//static void on_2D视口绘制(C_Widget* self, S_2D画布* 画布) {
//	C_2D编辑视口& box = *(C_2D编辑视口*)self;
//
//	box.m_背景 = f_vg_drawConvexElement((*self), *画布, E_填充模式::e_填充面, E_图层混合模式::e_Normal);
//	box.m_刻度 = f_vg_drawConvexElement((*self), *画布, E_填充模式::e_填充面, E_图层混合模式::e_Normal);
//
//}
//
//static void on_2D视口变换修改(C_Widget* self) {
//}


E_事件是否传递 f_2D页面_移动视口(C_Widget* self, E_键位执行状态 状态) {
	auto& view = *f_ui_get滚动框视口(self);

	view.f_setPos(view.m_Pos + C_Widget::g_鼠标.abs);
	//std::cout<<"C_Widget::g_鼠标.abs = "<< view.m_Scale.x << " : " << view.m_Scale.y << std::endl;
	f_Widget_应用视口移动(self);

	return E_事件是否传递::e_事件传递_终止;
}




C_Widget* f_工作区页面_创建2D视口(S_UI渲染环境& ctx) {
	C_2D编辑视口* ui2D编辑视口 = new C_2D编辑视口(ctx);

	static S_Object* 大纲数据 = nullptr;
	//f_ui_树形框_创建(ctx, 大纲数据);

	f_widget_开启视口属性(ui2D编辑视口);
	ui2D编辑视口->m_扩展视口属性->m_大小 = { 2048, 2048 };
	ui2D编辑视口->m_属性栏 = f_创建属性边栏(ctx);

	auto* 滚动窗口 = f_ui_创建滚动框(ctx, true, true, ui2D编辑视口);
	滚动窗口->mf_鼠标滚轮 = nullptr;
	滚动窗口->mf_布局 = on_2D视口布局;
	//滚动窗口->mf_绘制 = on_2D编辑视口绘制;
	//滚动窗口->mf_变换 = on_2D编辑视口变换修改;

	C_2D编辑视口::g当前操作2D编辑视口 = ui2D编辑视口;



	S_鼠标键位映射* 鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_缩放页面视口;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_滚轮;
	鼠标键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	鼠标键位->发生组件 = 滚动窗口;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)鼠标键位);

	S_拖拽键位映射* 拖拽键位 = f_widget_init_拖放键位映射();
	拖拽键位->event = f_2D页面_移动视口;
	拖拽键位->鼠标按键[0] = E_Input_鼠标按键::e_中键;
	拖拽键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	拖拽键位->发生组件 = 滚动窗口;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)拖拽键位);

	return 滚动窗口;
}
